/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package gace.dao;


import gace.basededatos.Conexion;
import gace.logica.Habitacion;
import gace.logica.Reserva;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;



/**
 *
 * @author Cast-Valv-HP
 */
public class ReservaDao {

    Connection conexion;

    public ReservaDao() throws SQLException{
        this.conexion =  Conexion.getConexion();
    }

    /**
     * Agrega una reserva a la bd. (El cliente debe estar previamente registrado en la bd).
     * @param r1 Objeto de tipo Reserva que representa un registro en la tabla
     * Reserva de la bd.
     */
    public void hacerReserva(Reserva r1) throws SQLException{

        String sql = "insert into reserva (fechaInicio, fechaFin, fecha, cliente_idcliente) values (?, ?, ?,?)";

        String autogenColumns[] = {"idreserva"};
        
       
        PreparedStatement stmt = conexion.prepareStatement(sql, autogenColumns);
        stmt.setDate(1, (Date) r1.getFechaInicio());
        stmt.setDate(2, (Date) r1.getFechaFin());
        stmt.setDate(3, (Date) r1.getFechaReserva());
        stmt.setInt(4, r1.getIdCliente());
        stmt.executeUpdate();

        // codigo para obtener el ultimo valor de la(s) llave(s)
        //

        int autoIncKeyFromFunc = -1;
        ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");

        if (rs.next()) {
            autoIncKeyFromFunc = rs.getInt(1);
        } else {
            // throw an exception from here
        }

        rs.close();
        r1.setId(autoIncKeyFromFunc);
        System.out.println("Key returned from " +
                       "'SELECT LAST_INSERT_ID()': " +
                       autoIncKeyFromFunc);
        //

        /* Crea un registro en la tabla reserva-habitacion*/

        String sql2 = "insert into reserva_habitacion (habitacion_idhabitacion, reserva_idreserva)"
                + "values (?, ?)";

        PreparedStatement stmt2 = conexion.prepareStatement(sql2);

        for (Habitacion h : r1.getHabitaciones()) {

            stmt2.setInt(1, h.getNumHabitacion());
            stmt2.setInt(2, autoIncKeyFromFunc);
            stmt2.execute();
            
        }

        stmt2.close();

        

    }

    /**
    * Calcula el total de tuplas o filas
    * @param r1 Objeto de tipo Reserva que representa un registro en la tabla
     * Reserva de la bd.
    */
    public void totalReservas (Reserva r1) throws SQLException{
        String sql3 = "select count(*) as Total from reserva";
        ResultSet rs = null;
        int rowCount = -1;
        PreparedStatement stmt = conexion.prepareCall(sql3);
        rs=stmt.executeQuery();
        rs.next();
        rowCount = rs.getInt(1);

       System.out.println("El Total de reservas: "+rowCount);
       rs.close();
      stmt.close();


    }

   /**
    * Elimina reserva de la bd. Esto implica ademas de eliminar el registro
    * en la tabla reserva, eliminar los registros en la tabla reserva-habitacion,
    * los cuales representan las habitaciones de las reservas.
    * @param r1 Objeto de tipo Reserva que representa un registro en la tabla
     * Reserva de la bd.
    */
    public void cancelarReserva(Reserva r1) throws SQLException{

        reservasExpiradas();


         /* Eliminar todas las relaciones entre reserva y habitacion
        en donde idReserva sea igual al numero de la reserva que
        se desea cancelar */
        String sql2 = "delete from reserva_habitacion where reserva_idreserva = ?";
        PreparedStatement stmt2 = conexion.prepareStatement(sql2);
        stmt2.setInt(1, r1.getId());
        stmt2.execute();
        stmt2.close();

        String sql = "delete from reserva where idreserva = ?";
        PreparedStatement stmt = conexion.prepareStatement(sql);
        stmt.setInt(1, r1.getId());
        stmt.execute();
        stmt.close();

        
    }

    /**
     * Elimina las reservas que han expirado, es decir, aquellas
     * cuya fecha de llegada es un dia menor a la fecha actual del
     * sistema. Es necesario consultar en la tabla renta para saber
     * si la reserva ha sido creada.
     */
    public void reservasExpiradas() throws SQLException{

        /* Eliminar reserva si ha pasado un dia desde que la reserva
        debia hacerse efectiva en una renta y si no hubo nunca checkin para
         esta reserva (de otro modo, no existiria en la tabla reserva) */

        String sql = "select * from reserva where fechaInicio < CURDATE() ";
        PreparedStatement stmt = conexion.prepareStatement(sql);
        ResultSet rs = stmt.executeQuery();
        //int numReservas = rs.getFetchSize();
        
        
        ArrayList<Integer> listaReservas = new ArrayList<Integer>();

        String sql2 = "delete from reserva where idreserva = ?";
        PreparedStatement stmt2 = conexion.prepareStatement(sql2);

        String sql3 = "delete from reserva_habitacion where reserva_idreserva = ?";
        PreparedStatement stmt3 = conexion.prepareStatement(sql3);

        // eliminar las reservas expiradas
        while(rs.next()){
                /* Eliminar los registros de la tabla reserva_habitacion con
                 id de reserva igual al encontrado en la primera consulta sql */
                stmt3.setInt(1, rs.getInt("idreserva"));
                stmt3.execute();
                stmt2.setInt(1, rs.getInt("idreserva"));
                listaReservas.add(rs.getInt("idreserva"));
                stmt2.execute();
        }
        stmt.close();
        rs.close();
        stmt3.close();
        stmt2.close();

        

    }

    /**
     * Retorna las reservas que tiene un cliente, dado el numero de su
     * id.
     * @param c1 el id del cliente
     * @return Las reservas que tiene un cliente
     * @throws SQLException
     */
    public ArrayList<Reserva> listarReservas(int c1) throws SQLException{
        String sql = "select * from reserva where cliente_idcliente = ?";
        PreparedStatement stmt = conexion.prepareStatement(sql);
        stmt.setInt(1, c1);
        ResultSet rs = stmt.executeQuery();
        ArrayList<Reserva> reservas = new ArrayList<Reserva>();

        while(rs.next()){
            Reserva r = new Reserva();
            r.setId(rs.getInt("idreserva"));
            r.setFechaFin(rs.getDate("fechaInicio"));
            r.setFechaFin(rs.getDate("fechaFin"));
            r.setFechaReserva(rs.getDate("fecha"));
            reservas.add(r);
        }
        return reservas;
    }


    public static void main(String args[]) throws SQLException{

//         Prueba1:  crear reserva
//        Reserva r = new Reserva();
//        Calendar cal = Calendar.getInstance();
//        cal.set(2011, 5, 4);
//        r.setFechaReserva(new Date(cal.getTimeInMillis()));
//        cal.set(2011, 5, 5);
//        r.setFechaInicio(new Date(cal.getTimeInMillis()));
//        cal.set(2011, 5, 6);
//        r.setFechaFin(new Date(cal.getTimeInMillis()));
//
//            // habitaciones reserva
//        ArrayList<Habitacion> habitaciones = new ArrayList<Habitacion>();
//        Habitacion h1 = new Habitacion();
//        h1.setNumHabitacion(1);
//        h1.setTipo("doble");
//        Habitacion h2 = new Habitacion();
//        h2.setNumHabitacion(2);
//        h1.setTipo("sencilla");
//        habitaciones.add(h1);
//        habitaciones.add(h2);
//        r.setHabitaciones(habitaciones);
//        r.setIdCliente(1);
//
//        ReservaDao rDAO = new ReservaDao();
//        rDAO.totalReservas(r);
//        rDAO.hacerReserva(r);


        // Prueba2:  cancelar reserva

//        Reserva r2 = new Reserva();
//        r2.setId(1);
//        ReservaDao rDAO2 = new ReservaDao();
//        rDAO2.cancelarReserva(r2);

        // Prueba3: eliminar reservas que expiraron

//        ReservaDao rDAO3 = new ReservaDao();
//        rDAO3.reservasExpiradas();

        // Prueba4: listar reservas de un cliente

//        ReservaDao rDAO4 = new ReservaDao();
//        ArrayList<Reserva> listarReservas = rDAO4.listarReservas(1);
//        for (Reserva reserva : listarReservas) {
//            System.out.println(reserva.getId());
//        }

    }

}

